package cn.hrbnu.interceptor;

import cn.hrbnu.enums.AppHttpCodeEnum;
import cn.hrbnu.po.User;
import cn.hrbnu.util.AuthContextUtil;
import cn.hrbnu.util.ResponseResult;
import com.alibaba.fastjson.JSON;
import org.jetbrains.annotations.NotNull;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author 薛旭辉
 * @version 1.0
 * &#064;ClassName  UserLoginAuthInterceptor
 * &#064;date  2025-06-11 10:18
 */

@Component
public class UserLoginAuthInterceptor implements HandlerInterceptor {

    private final RedisTemplate<String, String> redisTemplate;

    public UserLoginAuthInterceptor(RedisTemplate<String, String> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    /**
     * 在请求处理之前进行拦截处理
     *
     * @param request 请求对象，用于获取请求头中的Token
     * @param response 响应对象，用于渲染错误信息
     * @param handler 处理器对象，通常能够用于执行请求的处理器实例
     * @return boolean 返回值用于指示是否继续执行请求，true表示继续，false表示中断
     * &#064;throw  Exception 抛出异常表示拦截处理过程中出现错误
     */
    @Override
    public boolean preHandle(HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler) {
        //从请求头中获取Token
        String token = request.getHeader("Token");
        //如果Token为空，表示用户未登录或登录信息已过期
        if(!StringUtils.hasText(token)) {
            //返回错误信息，提示用户需要登录
            ResponseResult<Object> result = new ResponseResult<>().errorResult(AppHttpCodeEnum.NEED_LOGIN);
            renderString(response, JSON.toJSONString(result));
            return false;
        }
        //从Redis中获取用户信息，键名为"user:login:"加上Token值
        String user = redisTemplate.opsForValue().get("user:login:" + token);

        //如果用户信息为空，表示用户未登录或登录信息已过期
        if(!StringUtils.hasText(user)) {
            //返回错误信息，提示用户需要登录
            ResponseResult<Object> result = new ResponseResult<>().errorResult(AppHttpCodeEnum.NEED_LOGIN);
            renderString(response, JSON.toJSONString(result));
            return false;
        }

        //将用户信息解析为User对象，并设置到AuthContextUtil中，以便后续使用
        AuthContextUtil.set(JSON.parseObject(user, User.class));

        //继续执行请求
        return true;
    }

    public void renderString(HttpServletResponse response, String string){
        try {
            response.setStatus(200);
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            response.getWriter().print(string);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
